#include "progressarc.h"
#include <QPainter>

progressArc::progressArc(QWidget *parent) :
    QWidget(parent)
{
    //初始化变量值
    minValue = 0.0;
    maxValue = 100.0;
    value = 0.0;
    precision = 0;

    startAngle = 0;
    endAngle = 0;

    title = "测试";

    bgColor = Qt::transparent;
    arcColor = QColor("#22a3a9");
    textColor = QColor("#000000");
    titleColor = QColor("#22a3a9");
    baseColor = QColor("#b3b3b3");

    percent = true;
    arcWidth = 10;
}

progressArc::~progressArc()
{

}

void progressArc::paintEvent(QPaintEvent *)
{
    int width = this->width();
    int height = this->height();
    int side = qMin(width,height);

    //绘制准备，启用反锯齿，平移坐标轴中心，等比列缩放
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);

    //绘制背景
    if(bgColor != Qt::transparent){
        painter.setPen(Qt::NoPen);
        painter.fillRect(this->rect(),bgColor);
    }

    painter.translate(width / 2,height / 2);
    painter.scale(side / 200.0,side / 200.0);

    //绘制圆弧
    drawArc(&painter);
    //绘制当前值
    drawValue(&painter);
    //绘制标题
    drawTitle(&painter);
}

void progressArc::drawArc(QPainter *painter)
{
    int radius = 99 - arcWidth;
    painter->save();
    painter->setBrush(Qt::NoBrush);

    QPen pen;
    pen.setWidth(arcWidth);
    pen.setCapStyle(Qt::RoundCap);

    //计算总范围角度，当前范围角度，剩余值范围角度
    double angleAll = 360.0 -startAngle -endAngle;
    double angleCurrent = angleAll * ((value - minValue) / (maxValue-minValue));
    double angleOther = angleAll - angleCurrent;
    QRectF rect = QRectF(-radius,-radius,radius*2,radius*2);

    //绘制圆弧背景
    pen.setColor(baseColor);
    painter->setPen(pen);
    painter->drawArc(rect,(270 - startAngle - angleCurrent - angleOther)*16,angleOther*16);

    //绘制圆弧进度
    pen.setColor(arcColor);
    painter->setPen(pen);
    painter->drawArc(rect,(270 - startAngle - angleCurrent)*16,angleCurrent*16);

    painter->restore();
}

void progressArc::drawValue(QPainter *painter)
{
    int radius = 100;
    painter->save();
    painter->setPen(textColor);

    QFont font;
    font.setPixelSize(40);
    painter->setFont(font);

    QString strValue;
    if(percent){
        double temp = value / (maxValue - minValue) * 100;
        strValue = QString("%1%").arg(temp,0,'f',precision);
    }else {
        strValue = QString("%1%").arg((double)value,0,'f',precision);
    }

    QRectF textRect(-radius,0,radius*2,radius/3);
    painter->drawText(textRect,Qt::AlignCenter,strValue);

    painter->restore();
}

void progressArc::drawTitle(QPainter *painter)
{
    double radius = 100;
    painter->save();
    painter->setPen(titleColor);

    QFont font;
    font.setPixelSize(25);
    painter->setFont(font);

    QRectF textRect(-radius,-radius/2.5,radius*2,radius/3);
    painter->drawText(textRect,Qt::AlignCenter,title);

    painter->restore();
}

double progressArc::getMinValue()
{
    return minValue;
}

double progressArc::getMaxValue()
{
    return maxValue;
}

double progressArc::getValue()
{
    return value;
}

int progressArc::getPrecision()
{
    return precision;
}

int progressArc::getStartAngle()
{
    return startAngle;
}

int progressArc::getEndAngle()
{
    return endAngle;
}

QString progressArc::getTitle() const
{
    return title;
}

QColor progressArc::getBgColor() const
{
    return bgColor;
}

QColor progressArc::getArcColor() const
{
    return arcColor;
}

QColor progressArc::getTextColor() const
{
    return textColor;
}

QColor progressArc::getTitleColor() const
{
    return titleColor;
}

QColor progressArc::getBaseColor() const
{
    return baseColor;
}

bool progressArc::getPercent()
{
    return percent;
}

int progressArc::getArcWidth()
{
    return arcWidth;
}

void progressArc::setRange(double minValue, double maxValue)
{
    if(minValue >= maxValue){
        return;
    }
    this->minValue = minValue;
    this->maxValue = maxValue;

    if(value < minValue){
        setValue(minValue);
    }else if(value > maxValue){
        setValue(maxValue);
    }

    this->update();
}

void progressArc::setRange(int minValue, int maxValue)
{
    setRange((double)minValue,(double)maxValue);
}

void progressArc::setMinValue(double minValue)
{
    setRange((double)minValue,(double)maxValue);
}

void progressArc::setMaxValue(double maxValue)
{
    setRange((double)minValue,(double)maxValue);
}

void progressArc::setValue(double value)
{
    if(value == this->value){
        return;
    }

    if(value < minValue){
        value = minValue;
    }else if(value > maxValue){
        value = maxValue;
    }
    this->value = value;
    this->update();
}

void progressArc::setValue(int value)
{
    setValue((double)value);
}

void progressArc::setPrecision(int precision)
{
    if(this->precision != precision){
        this->precision = precision;
        this->update();
    }
}

void progressArc::setStartAngle(int startAngle)
{
    if(this->startAngle != startAngle){
        this->startAngle = startAngle;
        this->update();
    }
}

void progressArc::setEndAngle(int endAngle)
{
    if(this->endAngle != endAngle){
        this->endAngle = endAngle;
        this->update();
    }
}

void progressArc::setTitle(const QString &title)
{
    if(this->title.compare(title) != 0){
        this->title = title;
        this->update();
    }
}

void progressArc::setBgColor(const QColor &bgColor)
{
    if(this->bgColor != bgColor){
        this->bgColor = bgColor;
        this->update();
    }
}

void progressArc::setArcColor(const QColor &arcColor)
{
    if(this->arcColor != arcColor){
        this->arcColor = arcColor;
        this->update();
    }
}

void progressArc::setTextColor(const QColor &textColor)
{
    if(this->textColor != textColor){
        this->textColor = textColor;
        this->update();
    }
}

void progressArc::setTitleColor(const QColor &titleColor)
{
    if(this->titleColor != titleColor){
        this->titleColor = titleColor;
        this->update();
    }
}

void progressArc::setBaseColor(const QColor &baseColor)
{
    if(this->baseColor != baseColor){
        this->baseColor = baseColor;
        this->update();
    }
}

void progressArc::setPercent(bool percent)
{
    if(this->percent != percent){
        this->percent = percent;
        this->update();
    }
}

void progressArc::setArcWidth(int arcWidth)
{
    if(this->arcWidth != arcWidth){
        this->arcWidth = arcWidth;
        this->update();
    }
}
